import styles from "./Index.module.css";
import _ from "lodash";
import { Menu } from "../../components/Menu/Menu";
import { useEffect, useState, useRef } from "react";
import { goto } from "../../utils/common/common";
import { Rocket } from "../../components/Rocket/Rocket";
import { useHotKey } from "../../utils/utils/shortcut";
import React from "react";
import { useNavigate } from "react-router-dom";
import { useAppSelector } from "../../utils/store/hooks";
import { keywordApi } from "../../utils/backend/server";
import { KeywordType } from "../../utils/domain/keyword";

type recType = {
  q: string;
  p: boolean;
  s: string[];
};

function getRec_baidu(val: string) {
  let o = document.getElementById("script");
  let s = document.createElement("script");
  s.setAttribute("id", "script");
  s.src = `https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=${encodeURIComponent(
    val
  )}&cb=callBack`;
  o?.parentNode && o.parentNode.replaceChild(s, o);
}

let text = "";
let inputFocusing = true;
export default function () {
  const myRef = useRef<HTMLInputElement>(null);
  // const [recArr, setRecArr] = useState<string[]>([]);
  const [baiduRec, setBaiduRec] = useState<string[]>([]);
  const [keywordRec, setKeywordRec] = useState<KeywordType[]>([]);
  const [rec, setRec] = useState<string[]>([]);
  const [inputVal, setInputVal] = useState("");
  const [chosen, setChosen] = useState(-1);
  const [directive, setDirective] = useState(false);
  const [placeholder, setPlaceholder] = useState("never stop learning...");
  const store = useAppSelector((state) => state.device);
  const [showMenu, setShowMenu] = useState(true);
  const hotKey = useHotKey("p");
  const to = useNavigate();
  const [config, setConfig] = useState({
    wallpaper: localStorage.getItem("wallpaper") || "./wallpaper.jpg",
    width: window.screen.width * 1.1 + "px", //wallpaper
    height: window.screen.height * 1.1 + "px", //wallpaper
  });
  const collections = useAppSelector((state) => state.collection);

  const compareInput = (query: string, cb: () => void) => {
    setInputVal((input) => {
      if (query.toUpperCase() !== input.replace(/^ /, "").toUpperCase())
        return input;
      cb();
      return input;
    });
  };

  const getRec = async (search: string) => {
    getRec_baidu(search);
    const { list } = await keywordApi.fetchPlaceholders({
      search,
      pageSize: 100,
    });
    compareInput(search, () => {
      setKeywordRec(list);
    });
  };

  useEffect(() => {
    // pc menu height = 44px * rec.length + 44px - 15px
    const height =
      store.device === "computer"
        ? Math.min(rec.length * 44 + (rec.length && 15), 455)
        : Math.min(rec.length * 38 + (rec.length && 15), 357);
    document.documentElement.style.setProperty("--menuHeight", `${height}px`);
  }, [rec]);

  useEffect(() => {
    setRec([
      ...keywordRec.map((val) => `-->${val.keyName}:${val.url}`),
      ...baiduRec,
    ]);
  }, [baiduRec, keywordRec]);

  useEffect(() => {
    if (hotKey) {
      // location.href = "#/functions";
      to("functions");
    }
  }, [hotKey]);

  useEffect(() => {
    //dispatch(fetchCollectionList({}));
    function changeEvent() {
      if (document.visibilityState === "visible") {
        myRef?.current?.focus();
        //mobile wont trigger focus event when go back from another tab please be aware!!!
        focus();
        //
        const oldNode = document.getElementsByTagName("title")[0];
        const newNode = document.createElement("title");
        newNode.innerText = "laremehpe";
        oldNode?.parentNode?.replaceChild(newNode, oldNode);
      } else if (document.visibilityState === "hidden") {
        myRef?.current?.blur();
        //mobile wont trigger blur event either!!!
        blur();
        //
        const oldNode = document.getElementsByTagName("title")[0];
        const newNode = document.createElement("title");
        newNode.innerText = "waiting...";
        oldNode?.parentNode?.replaceChild(newNode, oldNode);
      }
    }

    function globalKeyEvent(val: KeyboardEvent) {
      if (val.keyCode === 27) {
        if (inputFocusing) myRef.current?.blur();
        else myRef.current?.focus();
      }

      // switchTab(val, "#/functions");
    }
    document.addEventListener("visibilitychange", changeEvent);
    document.addEventListener("keydown", globalKeyEvent);

    Object.assign(window, {
      callBack: (val: recType) => {
        // if (compareInput(val.q)) return; // return if request call back is not correspond with input value
        compareInput(val.q, () => {
          // setRecArr((arr) => {
          //   return [...arr.filter((val) => val.startsWith("--")), ...val.s];
          // });
          setBaiduRec(val.s);
        });
      },
    });

    const changeWallpaperSize = _.throttle(() => {
      setConfig((e) => ({
        ...e,
        width: window.screen.width * 1.1 + "px",
        height: window.screen.height * 1.1 + "px",
      }));
    }, 1000);
    window.addEventListener("resize", changeWallpaperSize);

    return () => {
      document.removeEventListener("visibilitychange", changeEvent);
      document.removeEventListener("keydown", globalKeyEvent);
      window.removeEventListener("resize", changeWallpaperSize);
    };
  }, []);

  const searchHandler: (val: { target: { value: string } }) => void = ({
    target: { value },
  }) => {
    setInputVal(value);
    setDirective(value.startsWith(" "));

    text = value;
    if (!value) {
      setRec([]);
      return;
    }
    getRec(value);
  };

  const resolveSearch = (inputVal: string, chosen: number) => {
    if (
      inputVal.startsWith("-->") &&
      inputVal === `-->${keywordRec[chosen].keyName}:${keywordRec[chosen].url}`
    ) {
      window.location.href = keywordRec[chosen].url;
      return;
    }

    goto(inputVal, collections.collectionList, () => {
      text = "";
      setInputVal("");
      setRec([]);
      setDirective(false); // set command font weight to normal
    });
  };

  function keyUp(val: { keyCode: number }) {
    switch (val.keyCode) {
      case 13: //enter
        resolveSearch(inputVal, chosen);
        break;
      case 38: //up
        updateChosen(chosen - 1 > -2 ? chosen - 1 : rec.length - 1);
        break;
      case 40: //down
        updateChosen(chosen + 1 > rec.length ? 0 : chosen + 1);
        break;
      default:
        setChosen(-1);
        break;
    }
  }

  function updateChosen(e: number) {
    setInputVal(rec[e] || text);
    setChosen(e);
  }

  function blur() {
    inputFocusing = false;
    setPlaceholder("");
    setChosen(-1);
    return;
    setShowMenu(false);
    //wait until animation finish
    setTimeout(() => {
      if (!inputFocusing) setPlaceholder("search");
    }, 500);
  }

  function focus() {
    inputFocusing = true;
    setShowMenu(true);
    setPlaceholder("never stop learning...");
  }

  return (
    <div className={styles.box}>
      <div
        style={{
          backgroundImage: `url(${config.wallpaper})`,
          // width: config.width,
          height: config.height,
        }}
        // alt="wallpaper"
        className={styles.wallpaper}
      />
      <div className={styles.headBox}></div>
      <div className={styles.logo}>
        <div className={styles.logoGap}></div>
        <button>
          <img
            src="./icon.png"
            alt="logo"
            title="stop and stare"
            id="logo"
            onClick={() => (
              localStorage.setItem("activePage", "0"),
              (window.location.href = "#/functions")
            )}
          />
        </button>
        <div className={styles.logoGap}></div>
      </div>
      <div
        className={[styles.frame, directive ? styles.directive : ""].join(" ")}
      >
        <input
          id="input"
          className={styles.input}
          type="text"
          value={inputVal}
          onChange={searchHandler}
          placeholder={placeholder}
          onKeyDown={keyUp}
          onFocus={focus}
          onBlur={blur}
          autoFocus
          ref={myRef}
          autoComplete="off"
          tabIndex={0}
        />
        <img
          src="./search.svg"
          alt="search logo"
          className={styles.searchIcon}
        />
        {inputVal?.length > 0 && placeholder !== "search" ? (
          <img
            src="./clear.png"
            alt="clear icon"
            tabIndex={1}
            onClick={(_) => {
              setInputVal("");
              // setRecArr([]);
              setRec([]);
              setDirective(false);
              myRef.current?.focus();
            }}
            className={styles.clearIcon}
          />
        ) : (
          ""
        )}
        <div className={styles.menu}>
          {/* 
            showMenu={showMenu}
           */}
          <Menu
            rec={rec}
            chosen={chosen}
            device={store.device === "computer"}
            updateChosen={(e) => {
              setChosen(e);
              setInputVal(rec[e]);
            }}
            clickItem={(chosen: number, e: string) => {
              setChosen(chosen);
              setInputVal(e);
              text = e;
              myRef.current?.focus();
              resolveSearch(e, chosen);
            }}
            onLeave={() => {
              setChosen(-1);
              setInputVal(text);
            }}
          />
        </div>
      </div>
      {store.device === "computer" ? <Rocket /> : ""}
    </div>
  );
}
